﻿using Chat.Framework;
using System;
using System.Net;
using System.Net.Sockets;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Windows;

namespace Chat.Client
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        //窗口闪烁代码
        public const uint FLASHW_STOP = 0;
        public const uint FLASHW_CAPTION = 1;
        public const uint FLASHW_TRAY = 2;
        public const uint FLASHW_ALL = 3;
        public const uint FLASHW_TIMER = 4;
        public const uint FLASHW_TIMERNOFG = 12;

        [DllImport("user32.dll")]
        static extern bool FlashWindowEx(ref FLASHWINFO pwfi);

        [DllImport("user32.dll")]
        static extern bool FlashWindow(IntPtr handle, bool invert);

        [DllImport("user32.dll")]
        public static extern IntPtr GetForegroundWindow();

        private Socket clientSocket = null;
        private static bool isListen = true;

        private void Sendbtn_OnClick(object sender, RoutedEventArgs e)
        {
            SendMessage();
        }

        private void SendMessage()
        {
            if (string.IsNullOrWhiteSpace(SendMsgtxt.Text.Trim()))
            {
                MessageBox.Show("发送的内容不能为空哦~");
                return;
            }

            if (clientSocket != null && clientSocket.Connected)
            {
                string sendMsg = EncryptionAndDecryption.TripleDESEncrypting($"{SendMsgtxt.Text}$");
                byte[] bytesSend = Encoding.UTF8.GetBytes(sendMsg);
                clientSocket.Send(bytesSend);
                SendMsgtxt.Text = "";
            }
            else
            {
                MessageBox.Show("未连接服务器或服务器已停止，请联系管理员~");
                return;
            }
        }


        private void Connectbtn_OnClick(object sender, RoutedEventArgs e)
        {
            if (string.IsNullOrWhiteSpace(UNametxt.Text.Trim()))
            {
                MessageBox.Show("还是设置一个用户名吧，这样别人才能认识你哦~");
                return;
            }

            if (clientSocket==null||!clientSocket.Connected)
            {
                try
                {
                    clientSocket=new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
                    clientSocket.BeginConnect(IPAddress.Loopback, 8080, (args) =>
                    {
                        if (args.IsCompleted)
                        {
                            byte[] bytesSend = new byte[4096];
                            UNametxt.Dispatcher.BeginInvoke(new Action(() =>
                            {
                                string tmp = EncryptionAndDecryption.TripleDESEncrypting($"{UNametxt.Text}$");
                                bytesSend = Encoding.UTF8.GetBytes(tmp);
                                if (clientSocket != null && clientSocket.Connected)
                                {
                                    clientSocket.Send(bytesSend);
                                    UNametxt.IsEnabled = false;
                                    SendMsgtxt.Focus();
                                    Thread th = new Thread(DataFromServer);
                                    th.IsBackground = true;
                                    th.Start();
                                }
                                else
                                {
                                    MessageBox.Show("服务器已经关闭");
                                }
                            }));
                        }
                    }, null);
                }
                catch (SocketException ex)
                {
                    MessageBox.Show(ex.ToString());
                }
            }
            else
            {
                MessageBox.Show("you has already connected with server");
            }
        }

        private void ShowMsg(string msg)
        {
            ReceiveMsgtxt.Dispatcher.BeginInvoke(new Action(() =>
            {
                ReceiveMsgtxt.Text += $"{Environment.NewLine}{msg}";
                ReceiveMsgtxt.ScrollToEnd();
                IntPtr handle = new System.Windows.Interop.WindowInteropHelper(this).Handle;
                if (this.WindowState == WindowState.Minimized || handle != GetForegroundWindow())
                {
                    FLASHWINFO fInfo = new FLASHWINFO();

                    fInfo.cbSize = Convert.ToUInt32(Marshal.SizeOf(fInfo));
                    fInfo.hwnd = handle;
                    fInfo.dwFlags = FLASHW_TRAY | FLASHW_TIMERNOFG;
                    fInfo.uCount = UInt32.MaxValue;
                    fInfo.dwTimeout = 0;

                    FlashWindowEx(ref fInfo);
                }
            }));
        }

        //获取服务端的消息
        private void DataFromServer()
        {
            ShowMsg("connected to the chat server...");
            isListen = true;
            try
            {
                while (isListen)
                {
                    byte[] bytesFrom=new byte[4096];
                    int len = clientSocket.Receive(bytesFrom);

                    string dataFromClientTmp = Encoding.UTF8.GetString(bytesFrom, 0, len);
                    if (!string.IsNullOrWhiteSpace(dataFromClientTmp))
                    {
                        string dataFromClient = EncryptionAndDecryption.TripleDESDecrypting(dataFromClientTmp);
                        if (dataFromClient.StartsWith("#")&&dataFromClient.EndsWith("#"))
                        {
                            string userName = dataFromClient.Substring(1, dataFromClient.Length - 2);
                            this.Dispatcher.BeginInvoke(new Action(() =>
                            {
                                MessageBox.Show($"用户名：[{userName}]已经存在，请尝试其他的用户名");
                            }));
                            isListen = false;
                            UNametxt.Dispatcher.BeginInvoke(new Action(() =>
                            {
                                UNametxt.IsEnabled = true;
                                clientSocket = null;
                            }));
                        }
                        else
                        {
                            ShowMsg(dataFromClient);
                        }
                    }
                }
            }
            catch (SocketException ex)
            {
                isListen = false;
                if (clientSocket!=null&&clientSocket.Connected)
                {
                    //我没有在客户端关闭连接而是向服务端发送一个消息，在服务器端关闭，这样主要
                    //为了异常的处理放到服务端。客户端关闭会抛异常，服务端也会抛异常。
                    clientSocket.Send(Encoding.UTF8.GetBytes(EncryptionAndDecryption.TripleDESEncrypting("$")));
                    MessageBox.Show(ex.ToString());
                }
            }
        }

        private void Window_Activated(object sender, EventArgs e)
        {
            SendMsgtxt.Focus();
        }

        private void Window_Closed(object sender, EventArgs e)
        {
            if (clientSocket!=null&&clientSocket.Connected)
            {
                clientSocket.Send(Encoding.UTF8.GetBytes(EncryptionAndDecryption.TripleDESEncrypting("$")));
            }
        }
    }

    public struct FLASHWINFO
    {
        public uint cbSize;
        public IntPtr hwnd;
        public uint dwFlags;
        public uint uCount;
        public uint dwTimeout;
    }
}
